package logic

import (
	"context"
	"fmt"

	"github.com/smartwalle/alipay/v3"

	"Junior_two/video/videorpc/internal/model"
	"Junior_two/video/videorpc/internal/utils"

	"math/rand"
	"net/http"
	"strconv"
	"time"

	"github.com/zeromicro/go-zero/core/logx"

	"Junior_two/video/videorpc/internal/svc"
	"Junior_two/video/videorpc/pb/videoRpc"
)

type OrderLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OrderLogic {
	return &OrderLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

//var (
//	//ali客户端
//	client *alipay.Client
//)

func init() {
	client, _ = alipay.New(appID, privateKey, false)
}

// Order 余额购买商品
func (l *OrderLogic) Order(in *videoRpc.OrderRequest) (*videoRpc.OrderResponse, error) {
	// todo: add your logic here and delete this line
	//根据商品ID获取商品数据
	g := model.GetGoodsDataByGoodId(in.GoodId)
	//计算总金额 单价（商品拍表中的商品单价）*数量（购买的数量）
	totalAmount := float64(in.GoodNum) * g.GoodsPrice
	//支付主题  第三放接口需要 尽量不要写死
	subject := "test" + fmt.Sprintf("%d", rand.Intn(10000))
	//第三方接口 订单编号 这里以时间戳的方式进行
	outTradeNo := time.Now().Unix()
	fmt.Println(outTradeNo)
	//购买商品 应当减少相应的商品库存 （在购买成功之前，需要判断一下商品库存是否充足，下面方法里面包含）
	if err := model.GoodNumReduce(in.GoodId, in.GoodNum); err != nil {
		return &videoRpc.OrderResponse{
			Msg:  err.Error(),
			Code: http.StatusConflict,
		}, nil
	}
	//支付方式 可以可无 无非就是添加一层支付方式的判断 但这里 只有支付宝
	if in.GoodType != "支付宝" {
		return &videoRpc.OrderResponse{
			Msg:  "暂不支持除支付宝以外的支付方式",
			Code: http.StatusConflict,
		}, nil
	}
	//既然是使用用户的余额进行购买商品 那么也应当减少用户的余额（快币） 在这里也应该进行判断用户的余额是否充足 （下面方法里面包含）
	if err := model.UserBalanceReduce(in.UserId, totalAmount); err != nil {
		return &videoRpc.OrderResponse{
			Msg:  err.Error(),
			Code: http.StatusConflict,
		}, nil
	}
	f := strconv.FormatFloat(totalAmount, 'f', 2, 64)
	//然后创建订单  也就是向订单表中添加数据
	if !model.CreateOrder(&model.Order{
		Id:          outTradeNo,
		GoodsId:     in.GoodId,
		GoodsNum:    in.GoodNum,
		TotalAmount: totalAmount,
		PayType:     in.GoodType,
		CreatedAt:   time.Now().Format(time.DateTime),
		UpdatedAt:   time.Now().Format(time.DateTime),
	}) {
		return &videoRpc.OrderResponse{
			Msg:  "购买失败",
			Code: http.StatusEarlyHints,
			Data: "",
		}, nil
	}
	//最后调用支付接口进行 支付宝支付 至于回调函数 有能力 可以写一写 这边建议可以写同步回调 异步回调不建议
	//将支付宝接口 返回出去 进行访问 也可以使用重定向 但是不好用这里就不做阐述了
	payUrl := utils.AliPay(subject, strconv.FormatInt(outTradeNo, 10), client, f)
	fmt.Println(6666)
	fmt.Println(payUrl)
	return &videoRpc.OrderResponse{
		Msg:  "请前往支付",
		Code: http.StatusOK,
		Data: payUrl,
	}, nil
}
